<template>
    <div class="flex flex-1 flex-col overflow-hidden">
        <div class="flex h-full overflow-hidden">
            <div :class=" fileLists.length <= 0 ? 'w-full': 'min-w-[540px] border-r border-br-extra-light'">
                <el-scrollbar>
                    <div class="p-4">
                        <el-upload
                            v-model:file-list="fileLists"
                            :headers="uploadParams.headers"
                            :action="uploadParams.action"
                            :data="uploadParams.data"
                            :accept="uploadParams.accept"
                            :limit="15"
                            :multiple="true"
                            :show-file-list="false"
                            :on-success="uploadSuccess"
                            drag
                        >
                            <div class="flex flex-col items-center mb-1">
                                <icon name="svg-icon-Upload" :size="46" color="var(--el-text-color-placeholder)" />
                                <span class="pt-2 text-base text-tx-regular">
                                    <el-button type="primary" link>点击上传</el-button> 或 拖拽文档到这里
                                </span>
                            </div>
                            <div class="text-sm text-tx-secondary">支持 .csv, .xlsx 类型文件</div>
                            <div class="text-sm text-tx-secondary">最多支持 15 个文件 单个文件最大 30 MB</div>
                            <el-button type="primary" link @click.stop="">
                                <a
                                    :href="config.baseUrl + '/static/xlsxTemplate.xlsx'"
                                    target="_blank"
                                    class="mt-1.5 font-normal"
                                >下载CSV模板</a>
                            </el-button>
                        </el-upload>

                        <ul v-if="fileLists.length > 0" class="file-list-box">
                            <li
                                v-for="(item, index) in fileLists"
                                :key="index"
                                :class="index === fileIndex ? 'active' : ''"
                                @click="handleChange(index)"
                            >
                                <el-image
                                    class="w-[24px] h-[24px] mr-2"
                                    :src="suffixUtil.findUnitIcon(item.name)"
                                />
                                <div class="flex-1">
                                    <h3>{{ item.name }}</h3>
                                    <div v-if="parseInt(String(item.percentage)) < 100" class="h-[18px] pr-10">
                                        <el-progress
                                            :percentage="item.percentage"
                                            :stroke-width="6"
                                            :duration="10"
                                            striped-flow
                                            striped
                                        />
                                    </div>
                                    <div v-else class="ml-1 text-xs text-tx-placeholder">
                                        {{ toolsUtil.formatBytes(item.size||0) }}
                                    </div>
                                </div>
                                <icon name="el-icon-Delete" :size="16" />
                            </li>
                        </ul>
                    </div>
                </el-scrollbar>
            </div>
            <div v-if="fileLists.length > 0" class="flex flex-col flex-1 overflow-hidden">
                <div class="px-4 pt-4 pb-2 text-base font-medium text-tx-regular">分段预览 (10)</div>
                <div v-loading="previewLoading" class="flex-1 overflow-hidden">
                    <el-scrollbar>
                        <div class="parse-list-box">
                            <div v-for="(item, index) in fileParse.lists" :key="index" class="parse-box">
                                <div class="title">
                                    <span class="section">#{{ index + 1 }}</span>
                                    <span class="m-2.5 font-medium text-tx-regular">
                                        {{ fileLists[fileIndex].name }}
                                    </span>
                                </div>
                                <div class="content">
                                    <p class="py-1.5">
                                        <span class="mr-2 text-tx-regular">问题:</span>
                                        <span class="text-tx-placeholder">{{ item.question }}</span>
                                    </p>
                                    <p class="py-1.5">
                                        <span class="mr-2 text-tx-regular">答案:</span>
                                        <span class="text-tx-placeholder">{{ item.answer }}</span>
                                    </p>
                                </div>
                            </div>
                        </div>
                    </el-scrollbar>
                </div>
            </div>
        </div>

        <div
            v-if="fileLists.length > 0"
            class="p-4 pb-2 flex items-center justify-end border-t border-br-extra-light"
        >
            <el-button
                class="ml-3 h-[38px]"
                :disabled="fileLists.length <= 0 || loading"
                @click="resetPreview(fileIndex)"
            >重新预览</el-button>
            <el-button
                class="ml-3 h-[38px]"
                type="primary"
                :disabled="fileLists.length <= 0 || previewLoading"
                :loading="loading"
                @click="handleSubmit"
            >确定导入</el-button>
        </div>
    </div>
</template>

<script setup lang="ts">
import type { UploadUserFile } from 'element-plus'
import config from '~/config/index'
import feedback from '~/utils/feedback'
import toolsUtil from '~/utils/tools'
import suffixUtil from '~/utils/suffix'
import useUserStore from '~/stores/user'
import knowArchiveApi from '~/api/agent/know/archive'

const emits = defineEmits(['retreat'])
const props = defineProps({
    kb: {
        type: String,
        default: ''
    }
})

// 上传参数
const uploadParams = ref({
    action: config.baseUrl + config.urlPrefix + '/upload/kb',
    accept: '.csv,.xlx,.xlsx',
    headers: {
        Authorization: 'Bearer ' + useUserStore().token,
        Terminal: config.terminal
    },
    data: {
        scene: 'csv'
    }
})

// 文件列表
const fileIndex = ref<number>(-1)
const fileLists = ref<UploadUserFile[]>([])
const fileParse = ref({} as KnowArchiveParseResponse)

// 预览加载
const previewLoading = ref<boolean>(false)

// 表单数据
const loading = ref<boolean>(false)
const formData = reactive({
    kb: props.kb,
    scene: 'csv',
    train_mode: 'chunk',
    chunk_type: 'automatic',
    chunk_size: 512,
    chunk_overlap: 0,
    separators: '',
    files: []
})

/**
 * 上传成功处理
 *
 * @param response
 * @param file
 * @author zero
 */
const uploadSuccess = (response: any, file: any) => {
    if (response.code === 0) {
        const index = fileLists.value.indexOf(file)
        fileLists.value[index].url = response.data.url
        if (fileIndex.value <= -1 && fileLists.value.length > 0) {
            fileIndex.value = 0
        }
    } else {
        fileLists.value.pop()
        feedback.msgError(response.msg)
    }
}

/**
 * 重新预览
 */
const resetPreview = async (index: number) => {
    previewLoading.value = true
    const fileUrl = fileLists.value[index].url
    fileParse.value = await knowArchiveApi.parse({
        kb: formData.kb,
        scene: formData.scene,
        chunk_size: formData.chunk_size,
        separators: formData.separators,
        chunk_overlap: formData.chunk_overlap,
        url: String(fileUrl)
    }).finally(() => {
        setTimeout(() => {
            previewLoading.value = false
        }, 1000)
    })
}

/**
 * 文件切换
 *
 * @param {number} index
 * @author zero
 */
const handleChange = (index: number) => {
    const file = fileLists.value[index]
    const percentage = parseInt(String(file.percentage))
    if (fileIndex.value === index) {
        return
    } else if (percentage < 100 || !file.url) {
        return feedback.msgError('请耐心等待上传完毕')
    }

    fileIndex.value = index
}

/**
 * 提交导入
 */
const handleSubmit = async () => {
    loading.value = true
    await knowArchiveApi.imports({
        kb: formData.kb,
        scene: formData.scene,
        train_mode: formData.train_mode,
        chunk_size: formData.chunk_size,
        chunk_overlap: formData.chunk_overlap,
        separators: formData.separators,
        files: fileLists.value
    }).finally(() => {
        loading.value = false
    })

    feedback.msgSuccess('导入成功')
    emits('retreat')
}

watch(
    () => fileIndex.value,
    async (index: number) => {
        await resetPreview(index)
    }
)
</script>

<style scoped lang="scss">
.file-list-box {
    margin-top: 15px;
    li {
        display: flex;
        align-items: center;
        width: 100%;
        padding: 8px 14px;
        margin-bottom: 12px;
        cursor: pointer;
        border: 1px solid var(--el-border-color-light);
        border-radius: 8px;
        &.active {
            border-color: var(--el-color-primary);
        }
        .el-icon:hover {
            color: var(--el-color-error);
        }
        h3 {
            margin: 0 4px;
            font-size: 14px;
            color: var(--el-text-color-regular);
        }
    }
}

.parse-list-box {
    .parse-box {
        box-sizing: border-box;
        margin: 0 16px 12px;
        border: 1px solid var(--el-border-color-lighter);
        border-radius: 6px;
        .title {
            padding: 10px;
            font-size: 15px;
            font-weight: 700;
            border-bottom: 1px solid var(--el-border-color-lighter);
            .section {
                padding: 2px 10px;
                font-size: 13px;
                color: var(--el-color-primary);
                background-color: var(--el-bg-color-page);
                border-radius: 4px;
            }
        }
        .content {
            padding: 8px 15px;
            background-color: var(--el-bg-color-page);
        }
    }
}
</style>
